package com.example.dl645.protocol.dl645;

/**
 * DL/T 645协议帧构建工具
 */
public class Dl645Frame {
    private byte[] address;
    private byte controlCode;
    private byte[] dataIdentifier; // 4字节数据标识（小端）

    public Dl645Frame(byte[] address, byte controlCode, byte[] dataIdentifier) {
        this.address = address;
        this.controlCode = controlCode;
        this.dataIdentifier = dataIdentifier;
    }

    /**
     * 转为字节数组（DL/T 645帧格式）
     */
    public byte[] toBytes() {
        // 帧结构：68 + 地址(6) + 68 + 控制码(1) + 数据长度(1) + 数据标识(4) + 校验码(1) + 16
        byte[] frameHeader = new byte[]{(byte) 0x68};
        byte dataLen = 4;
        byte[] dataField = dataIdentifier;

        // 计算校验码（从帧头1到数据域末尾的模256和）
        byte checksum = 0;
        checksum = (byte) ((checksum + frameHeader[0]) & 0xFF);
        for (byte b : address) checksum = (byte) ((checksum + b) & 0xFF);
        checksum = (byte) ((checksum + frameHeader[0]) & 0xFF); // 帧头2
        checksum = (byte) ((checksum + controlCode) & 0xFF);
        checksum = (byte) ((checksum + dataLen) & 0xFF);
        for (byte b : dataField) checksum = (byte) ((checksum + b) & 0xFF);

        // 拼接完整帧
        byte[] frame = new byte[1 + 6 + 1 + 1 + 1 + 4 + 1 + 1];
        int index = 0;
        index = addBytes(frame, index, frameHeader); // 帧头1
        index = addBytes(frame, index, address); // 地址
        index = addBytes(frame, index, frameHeader); // 帧头2
        frame[index++] = controlCode; // 控制码
        frame[index++] = dataLen; // 数据长度
        index = addBytes(frame, index, dataField); // 数据标识
        frame[index++] = checksum; // 校验码
        frame[index++] = (byte) 0x16; // 帧尾
        return frame;
    }

    private int addBytes(byte[] dest, int destPos, byte[] src) {
        System.arraycopy(src, 0, dest, destPos, src.length);
        return destPos + src.length;
    }
}